package com.datauuu.practice.algorithm.linear.impl;

import com.datauuu.practice.algorithm.linear.IArrayList;

import java.util.Arrays;
import java.util.Iterator;


/**
 * 我的arrayList
 *
 * @author sunym1993
 * @version 0.0.1-SNAPSHOT
 * @since 2017年10月31日 18时51分
 */
public class MyArrayList<T> implements IArrayList<T> {

    private static final int DEFAULT_CAPACITY = 10;

    private T[] array;

    private int size;

    public MyArrayList() {
        this(DEFAULT_CAPACITY);
    }

    public MyArrayList(int capacity) {
        this.size = 0;
        array = (T[]) new Object[capacity];
    }

    @Override
    public T get(int index) {
        checkIndex(index);
        return array[index];
    }

    @Override
    public T set(int index, T value) {
        checkIndex(index);
        T old = array[index];
        array[index] = value;
        return old;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return size()==0;
    }

    @Override
    public void clear() {
        doClear(DEFAULT_CAPACITY);
    }

    private void doClear(int capacity){
        this.size = 0;
        array = (T[]) new Object[capacity];
    }

    @Override
    public T remove(int index) {
        checkIndex(index);
        T value = array[index];
        for (int i = index; i<size-1; i++ ) {
            array[i] = array[i+1];
        }
        size--;
        return value;
    }

    @Override
    public boolean add(T value) {
        ensureCapacity(++size);
        array[size-1] = value;
        return true;
    }

    @Override
    public boolean add(int index, T value) {
        checkIndex(index);
        ensureCapacity(++size);
        for (int i = size-1; i>index; i-- ) {
            array[i] = array[i-1];
        }
        array[index]=value;
        return true;
    }

    @Override
    public Iterator<T> iterator(){
        return new ArrayListIterator<>(this);
    }

    private static class ArrayListIterator<T> implements Iterator<T> {

        private int current = 0;
        private MyArrayList<T> theList;

        public ArrayListIterator(MyArrayList<T> list) {
            this.theList = list;
        }

        @Override
        public boolean hasNext() {
            return current < theList.size();
        }

        @Override
        public T next() {
            return theList.array[current++];
        }
    }


    public void print(){
        System.out.println(Arrays.toString(array) + "--->" + size);
    }

    /**
     * 如果需要的话，进行扩容
     * @param size
     */
    private void ensureCapacity(int size){
        int oldLenght = array.length;
        if (size > oldLenght) {
            T[] newArray = (T[]) new Object[oldLenght*2];
            for (int i = 0; i<oldLenght; i++) {
                newArray[i] = array[i];
            }
        }
    }

    /**
     * 检查索引越界问题，如果有则抛出运行时异常
     * @param index
     */
    private void checkIndex(int index){
        // 判断索引越界问题
        if (index < 0 || index >= size()) {
            throw new ArrayIndexOutOfBoundsException(String.format(
                "ArrayList索引越界异常，当前索引：%d，集合总大小：%d", index, size()
            ));
        }
    }
}
